﻿// Decompiled with JetBrains decompiler
// Type: TaleWorlds.CampaignSystem.CharacterRelationManager
// Assembly: TaleWorlds.CampaignSystem, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: E85F8C15-4DF6-4E9C-A58A-29177E40D07A
// Assembly location: D:\steam\steamapps\common\Mount & Blade II Bannerlord\bin\Win64_Shipping_Client\TaleWorlds.CampaignSystem.dll

using System.Collections.Generic;
using System.Linq;
using TaleWorlds.Core;
using TaleWorlds.Library;
using TaleWorlds.SaveSystem;

#nullable disable
namespace TaleWorlds.CampaignSystem
{
  public class CharacterRelationManager
  {
    [SaveableField(1)]
    private readonly CharacterRelationManager.HeroRelations _heroRelations;

    internal static void AutoGeneratedStaticCollectObjectsCharacterRelationManager(
      object o,
      List<object> collectedObjects)
    {
      ((CharacterRelationManager) o).AutoGeneratedInstanceCollectObjects(collectedObjects);
    }

    protected virtual void AutoGeneratedInstanceCollectObjects(List<object> collectedObjects)
    {
      collectedObjects.Add((object) this._heroRelations);
    }

    internal static object AutoGeneratedGetMemberValue_heroRelations(object o)
    {
      return (object) ((CharacterRelationManager) o)._heroRelations;
    }

    public static CharacterRelationManager Instance => Campaign.Current.CharacterRelationManager;

    public CharacterRelationManager()
    {
      this._heroRelations = new CharacterRelationManager.HeroRelations();
    }

    public static int GetHeroRelation(Hero hero1, Hero hero2)
    {
      return CharacterRelationManager.Instance._heroRelations.GetRelation(hero1, hero2);
    }

    public static void SetHeroRelation(Hero hero1, Hero hero2, int value)
    {
      if (hero1 != hero2)
        CharacterRelationManager.Instance._heroRelations.SetRelation(hero1, hero2, value);
      else
        Debug.FailedAssert("hero1 != hero2", "C:\\Develop\\MB3\\Source\\Bannerlord\\TaleWorlds.CampaignSystem\\CharacterRelationManager.cs", nameof (SetHeroRelation), 262);
    }

    public void AfterLoad()
    {
      if (!(MBSaveLoad.LastLoadedGameVersion < ApplicationVersion.FromString("v1.1.0")))
        return;
      this._heroRelations.ClearOldData();
    }

    public void RemoveHero(Hero deadHero) => this._heroRelations.Remove(deadHero);

    internal class HeroRelations
    {
      [SaveableField(1)]
      private Dictionary<long, Dictionary<long, int>> _relations = new Dictionary<long, Dictionary<long, int>>();

      internal static void AutoGeneratedStaticCollectObjectsHeroRelations(
        object o,
        List<object> collectedObjects)
      {
        ((CharacterRelationManager.HeroRelations) o).AutoGeneratedInstanceCollectObjects(collectedObjects);
      }

      protected virtual void AutoGeneratedInstanceCollectObjects(List<object> collectedObjects)
      {
        collectedObjects.Add((object) this._relations);
      }

      internal static object AutoGeneratedGetMemberValue_relations(object o)
      {
        return (object) ((CharacterRelationManager.HeroRelations) o)._relations;
      }

      public int GetRelation(Hero hero1, Hero hero2)
      {
        (long, long) hashCodes = this.GetHashCodes(hero1, hero2);
        Dictionary<long, int> dictionary;
        int num;
        return this._relations.TryGetValue(hashCodes.Item1, out dictionary) && dictionary.TryGetValue(hashCodes.Item2, out num) ? num : 0;
      }

      public void SetRelation(Hero hero1, Hero hero2, int value)
      {
        (long, long) hashCodes = this.GetHashCodes(hero1, hero2);
        if (value != 0)
        {
          Dictionary<long, int> dictionary;
          if (!this._relations.TryGetValue(hashCodes.Item1, out dictionary))
          {
            dictionary = new Dictionary<long, int>();
            this._relations.Add(hashCodes.Item1, dictionary);
          }
          dictionary[hashCodes.Item2] = value;
        }
        else
        {
          Dictionary<long, int> source;
          if (!this._relations.TryGetValue(hashCodes.Item1, out source) || !source.ContainsKey(hashCodes.Item2))
            return;
          source.Remove(hashCodes.Item2);
          if (source.Any<KeyValuePair<long, int>>())
            return;
          this._relations.Remove(hashCodes.Item1);
        }
      }

      public void Remove(Hero hero)
      {
        int hashCode = hero.Id.GetHashCode();
        this._relations.Remove((long) hashCode);
        foreach (Dictionary<long, int> dictionary in this._relations.Values)
          dictionary.Remove((long) hashCode);
      }

      public void ClearOldData()
      {
        this.ClearOldData<Dictionary<long, int>>(this._relations);
        foreach (Dictionary<long, int> dictionary in this._relations.Values)
          this.ClearOldData<int>(dictionary);
      }

      private void ClearOldData<T>(Dictionary<long, T> obj)
      {
        HashSet<long> longSet = new HashSet<long>((IEnumerable<long>) obj.Keys);
        foreach (Hero aliveHero in (List<Hero>) Campaign.Current.CampaignObjectManager.AliveHeroes)
        {
          if (longSet.Contains((long) aliveHero.Id.GetHashCode()))
            longSet.Remove((long) aliveHero.Id.GetHashCode());
        }
        foreach (long key in longSet)
          obj.Remove(key);
      }

      private (long, long) GetHashCodes(Hero hero1, Hero hero2)
      {
        return hero1.Id > hero2.Id ? ((long) hero1.Id.GetHashCode(), (long) hero2.Id.GetHashCode()) : ((long) hero2.Id.GetHashCode(), (long) hero1.Id.GetHashCode());
      }
    }
  }
}
